package ru.spies.loginOrRegistration;

import java.util.Random;

public class PasswordGenerator {
	
	private static PasswordGenerator statThis;
	
	private static final int ADD_CONST_FIRST=58;
	private static final int ADD_CONST_SECOND=37;
	private static final int ADD_CONST_THIRD=1;
	private static final int LIMIT_FIRST=48;
	private static final int LIMIT_SECOND=128;
	private static final int LIMIT_THIRD=255;
	private static final int LIMIT_FORTH=254;
	private static final int MIN_PASS_LENGTH=8;
	private static Random rnd=null;
	
	private PasswordGenerator() {
		rnd = new Random();
	}
	
	public static PasswordGenerator getInstance(){
		if (statThis==null){
			statThis=new PasswordGenerator();
		}
		return statThis;
	}
	
	private String tranformPassword(String password){
		StringBuffer newPassword= new StringBuffer();
		for (int i = 0; i < password.length(); i++) {
			newPassword.append(transformChar(password.charAt(i)));
		}
		String buf=newPassword.toString();
		newPassword = new StringBuffer();
		int j=buf.length()-1;
		for (int i = 0; i < buf.length(); i++) {
			newPassword.append(buf.charAt(i));
			newPassword.append(buf.charAt(j));
			j--;
		}
		return newPassword.toString();
	}
	
	private char transformChar(char oldChar){
		int limit;
		if ((int)oldChar<LIMIT_FIRST){
			limit=LIMIT_FIRST;
		} else {
			if ((int)oldChar<LIMIT_SECOND){
				limit=LIMIT_SECOND;
			} else {
				if ((int)oldChar<LIMIT_THIRD){
					limit=LIMIT_THIRD;
				} else {
					limit=LIMIT_FORTH;
				}
			}
		}
		char newChar;
		switch (limit) {
		case LIMIT_FIRST:
			newChar=(char)((int)oldChar+ADD_CONST_FIRST);
			break;
		case LIMIT_SECOND:
			newChar=(char)((int)oldChar+ADD_CONST_SECOND);
			break;
		case LIMIT_THIRD:
			newChar=(char)((int)oldChar+ADD_CONST_THIRD);
			break;
		default:
			newChar=(char)((int)oldChar-ADD_CONST_THIRD);
			break;
		}
		while (!goodChar(newChar)){
			newChar=convertCharToNormal(newChar);
		}
		return newChar;
	}
	
	private char convertCharToNormal(char oldChar){
		int code=(int)oldChar;
		if (code>=229){
			code-=133;
		} else {
			if (code>=203){
				code-=106;
			} else {
				if (code>=193){
					code-=145;
				} else {
					if (code>=167){
						code-=102;
					} else {
						if (code>=157){
							code-=109;
						} else {
							if (code>=123){
								code-=26;
							} else {
								if (code>=91){
									code-=26;
								} else {
									if (code>=58){
										code+=39;
									} else {
										if (code>=38){
											code+=10;
										} else {
											if (code>=12){
												code+=53;
											} else {
												code+=97;
											}
										}
									}
								}
							}
						}
					}
				}
			}
		}
		char newChar=(char)code;
		return newChar;
	}
	
	public String getRandomPassword(){
		StringBuffer password= new StringBuffer();
		for (int i = 0; i<MIN_PASS_LENGTH; i++){
			char nextChar;
			do {
				nextChar=(char)rnd.nextInt(LIMIT_THIRD/2);
			} while(!goodChar(nextChar));
			password.append(nextChar);
		}
		return password.toString();
	}
	
	public boolean checkPasswordForASCII(String password){
		for (int i = 0; i < password.length(); i++) {
			char next = password.charAt(i);
			if (!goodChar(next)){
				return false;
			}
		}
		return true;
	}
	
	private boolean goodChar(char checkChar){
		int code=(int)checkChar;
		if (((code>47)&&(code<58))||((code>64)&&(code<91))||((code>96)&&(code<122))) return true;	
		return false;
	}
	
	public boolean isPasswordRight(String inPass, String existingPass){
		inPass=tranformPassword(inPass);
		if (inPass.equals(existingPass)){
			return true;
		}
		return false;
	}
	
	public String preparePasswordToSave(String password){
		return tranformPassword(password);
	}
	
}
